package com.szewec.ps.base;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.szewec.ps.R;
import com.szewec.ps.model.FindFileModel;
import com.szewec.ps.myinterface.IFinishUploadCallback;
import com.szewec.ps.myinterface.IRequestFileCallback;
import com.szewec.ps.myview.toast.bamtoast.BamToast;
import com.szewec.ps.util.BitmapFileSetting;
import com.szewec.ps.util.CommonUtils;
import com.szewec.ps.util.GPSUtils;
import com.szewec.ps.util.GsonUtil;
import com.szewec.ps.util.LocationUtils;
import com.szewec.ps.util.LogUtil;
import com.szewec.ps.util.PhotoVideoUtil;
import com.szewec.ps.util.PreferincesContext;
import com.szewec.ps.util.dialog.LoadingDialog;
import com.szewec.ps.util.imagepicker.GlideLoader;
import com.szewec.ps.util.imagepicker.ImagePicker;
import com.szewec.ps.util.imagepicker.MedioRecorderCamera1Activity;
import com.szewec.ps.util.imagepicker.SelectDialog;
import com.szewec.ps.util.imagepicker.activity.ImagePreActivity;
import com.szewec.ps.util.imagepicker.adapter.CustomPickerAdapterShowAndEdit;
import com.szewec.ps.util.imagepicker.data.MediaFile;
import com.szewec.ps.util.imagepicker.manager.SelectionManager;
import com.szewec.ps.util.imagepicker.utils.DataUtil;
import com.szewec.ps.util.okhttp.OkHttp;
import com.szewec.ps.util.ossservice.OssService;
import com.szewec.ps.util.ossservice.OssServiceUtil;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.UUID;

import okhttp3.Response;

import static android.content.ContentValues.TAG;

public class BaseMediaPickerActivity extends BaseActivity {
    private Context _mContext;

    // 加载菊花
    private LoadingDialog _loadingDialog;

    // 图片选择相关
    protected ImagePicker _imagePicker;

    // 拍照图片保存的路径
    protected String _capturePicFilePath;

    // 拍照或者录制视频的文件路径
    protected String _captureFilePath;

    //OSS相关对象
    private OssService _ossService;
    private UploadFileHandler _uploadFileHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        _mContext = this;
        _loadingDialog = LoadingDialog.getInstance(this);
        initImagePicker();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String captureOrVideoFilePath = null;
        if (resultCode == RESULT_OK && data != null) {
            //视频拍摄返回获取路径
            captureOrVideoFilePath = data.getStringExtra(PreferincesContext.FILEPATH);
        }
        //如果为空，表示不是视频录制模式，而且照片的不为空，表示是拍照模式
        if (captureOrVideoFilePath == null && _capturePicFilePath != null) {
            captureOrVideoFilePath = _capturePicFilePath;
        }
        _captureFilePath = captureOrVideoFilePath;

        if (resultCode == RESULT_OK) {
            //通知媒体库刷新
            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + _captureFilePath)));
        }
    }

    private void initImagePicker() {
        _imagePicker = ImagePicker.getInstance();
        _imagePicker.setTitle("照片及视频")//设置标题
                .showCamera(false)//设置是否显示拍照按钮
                .showImage(true)//设置是否展示图片
                .showVideo(true)//设置是否展示视频
                .setSingleType(false)//设置图片视频不能同时选择
                .setMaxCount(999)//设置最大选择图片数目(默认为1，单选)
                .setImageLoader(new GlideLoader());//设置自定义图片加载器
    }

    @SafeVarargs
    protected final String getAddIdsStr(List<String>... listList) {
        List<String> strList = new ArrayList<>();
        for (List<String> list : listList) {
            strList.addAll(list);
        }

        String addIds = "";
        if (strList.size() > 0) {
            addIds = TextUtils.join(",", strList);
        }
        return addIds;
    }

    protected CustomPickerAdapterShowAndEdit initTypeMediaRecyclerView(List<String> uploadIdList,
                                                                       ArrayList<MediaFile> mediaFileList, RecyclerView recyclerView,
                                                                       Boolean isShowCameraBtn, boolean canPickVideo, boolean canPickPic, List<String> deletePhotoIdArr) {

        CustomPickerAdapterShowAndEdit innerAdapter = new CustomPickerAdapterShowAndEdit(this, mediaFileList, isShowCameraBtn, true);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
        //注释说当知道Adapter内Item的改变不会影响RecyclerView宽高的时候，可以设置为true让RecyclerView避免重新计算大小。
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(innerAdapter);

        innerAdapter.setOnItemClickListener(new CustomPickerAdapterShowAndEdit.OnItemClickListener() {
            @Override
            public void onMediaClick(View view, int position) {
                if (isShowCameraBtn) {
                    if (position == innerAdapter.getItemCount() - 1) {
                        List<String> names = new ArrayList<>();

                        if (canPickVideo && !canPickPic) {
                            _imagePicker.showVideo(true);
                            _imagePicker.showImage(false);
                            names.add(FileUpload.MediaFileAchieveWayEnum.RECORDING.getValue());
                            names.add(FileUpload.MediaFileAchieveWayEnum.LOCAL_GALLERY.getValue());
                        } else if (!canPickVideo && canPickPic) {
                            _imagePicker.showVideo(false);
                            _imagePicker.showImage(true);
                            names.add(FileUpload.MediaFileAchieveWayEnum.PHOTOGRAPH.getValue());
                            names.add(FileUpload.MediaFileAchieveWayEnum.LOCAL_GALLERY.getValue());
                        } else if (canPickVideo && canPickPic) {
                            _imagePicker.showVideo(true);
                            _imagePicker.showImage(true);
                            names.add(FileUpload.MediaFileAchieveWayEnum.PHOTOGRAPH.getValue());
                            names.add(FileUpload.MediaFileAchieveWayEnum.RECORDING.getValue());
                            names.add(FileUpload.MediaFileAchieveWayEnum.LOCAL_GALLERY.getValue());
                        }

                        showDialog(new SelectDialog.SelectDialogListener() {
                            @Override
                            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                                String name = names.get(position);
                                if (FileUpload.MediaFileAchieveWayEnum.PHOTOGRAPH.getValue().equals(name)) {
                                    //直接调起相机
                                    _capturePicFilePath = PhotoVideoUtil.showCamera(BaseMediaPickerActivity.this, System.identityHashCode(innerAdapter) + FileUpload.MediaFileAchieveWayEnum.PHOTOGRAPH.getKey());
                                } else if (FileUpload.MediaFileAchieveWayEnum.RECORDING.getValue().equals(name)) {
                                    //录制视频
                                    startActivityForResult(new Intent(BaseMediaPickerActivity.this, MedioRecorderCamera1Activity.class), System.identityHashCode(innerAdapter) + FileUpload.MediaFileAchieveWayEnum.RECORDING.getKey());
                                } else if (FileUpload.MediaFileAchieveWayEnum.LOCAL_GALLERY.getValue().equals(name)) {
                                    _imagePicker.start(BaseMediaPickerActivity.this, System.identityHashCode(innerAdapter) + FileUpload.MediaFileAchieveWayEnum.LOCAL_GALLERY.getKey());
                                }
                            }
                        }, names);
                        return;
                    }
                }

                //打开大图预览
                if (mediaFileList != null) {
                    DataUtil.getInstance().setMediaData(mediaFileList);
                    Intent intent = new Intent(BaseMediaPickerActivity.this, ImagePreActivity.class);
                    intent.putExtra(ImagePreActivity.IMAGE_POSITION, position);
                    startActivityForResult(intent, 0x000000);
                }
            }

            @Override
            public void onMediaCheck(View view, int position) {
            }
        });

        innerAdapter.setOnDeleteClickListener(new CustomPickerAdapterShowAndEdit.OnDeleteClickListener() {
            @Override
            public void onDeleteClick(View view, int position) {
                //保存删除的图片ID
                deletePhotoIdArr.add(uploadIdList.get(position));
                //删除显示列表中的图片
                innerAdapter.remove(position);
                //已经上传致服务器的文件id数组
                uploadIdList.remove(position);
            }
        });

        return innerAdapter;
    }

    // 请求指定的文件列表。然后下载附件
    protected void requestFiles(FileUpload.RoadInvestigationFileBizTypeEnum fileBizTypeEnum, String bizId, IRequestFileCallback iRequestFileCallback) {
        HashMap<String, Object> param = new HashMap<>();
        param.put("pageIndex", 1);
        param.put("pageSize", 999);
        param.put("orderBy", "createTime");
        param.put("bizType", fileBizTypeEnum.getKey());
        param.put("bizId", bizId);
        OkHttp.get("/tpms-file-service/api/file", param, _loadingDialog, (result -> {
            Log.i(TAG, "file result is：" + result);
            FindFileModel findFileModel = JSONObject.parseObject(result, FindFileModel.class);
            List<FindFileModel.DataBean> data = findFileModel.getData();
            if (null != data && data.size() > 0) {
                List<MediaFile> mediaFileList = new ArrayList<>();
                for (int i = 0; i < data.size(); i++) {
                    FindFileModel.DataBean dataBean = data.get(i);
                    MediaFile mediaFile = findFileModelToMediaFile(dataBean);
                    mediaFileList.add(mediaFile);
                }
                iRequestFileCallback.finishCheck(mediaFileList);
            }
        }));
    }

    // 根据附件ID请求指定的文件列表。然后下载附件
    protected void requestFilesByIds(List<String> ids, IRequestFileCallback iRequestFileCallback) {
        HashMap<String, Object> param = new HashMap<>();
        param.put("ids", CommonUtils.listToStringCommaSplicing(ids));
        OkHttp.get("/tpms-file-service/api/file/get-by-ids", param, _loadingDialog, (result -> {
            Log.i(TAG, "file by id result is：" + result);
            List<FindFileModel.DataBean> data = JSONArray.parseArray(result,FindFileModel.DataBean.class);
            if (null != data && data.size() > 0) {
                List<MediaFile> mediaFileList = new ArrayList<>();
                for (int i = 0; i < data.size(); i++) {
                    FindFileModel.DataBean dataBean = data.get(i);
                    MediaFile mediaFile = findFileModelToMediaFile(dataBean);
                    mediaFileList.add(mediaFile);
                }
                iRequestFileCallback.finishCheck(mediaFileList);
            }
        }));
    }


    //设置mediaFileList
    protected MediaFile findFileModelToMediaFile(FindFileModel.DataBean file) {
        String type = file.getType().toLowerCase();
        MediaFile mediaFile = new MediaFile();
        String path = "";
        long duration = 0;
        if (CommonUtils.isPicture(type)) {
            path = BaseUrl.OSS_URI + file.getFileKey();
            mediaFile.setType(FileUpload.MediaFileTypeEnum.PHOTO_FILE.getKey());// 0表示照片，1表示视频
        } else if (CommonUtils.isVideo(type)) {
            if ("plan-app".equals(BaseUrl.APP_NUMBER)) {
                //测试环境
                path = "http://video.gcnao.cn/video/21bb3ab8-167cf0c39fe-0000-0000-013-eec4b.mp4";
                duration = 1;//传大于0的时长  用于判断选对应格式的item布局
                mediaFile.setUrl("http://video.gcnao.cn/video/21bb3ab8-167cf0c39fe-0000-0000-013-eec4b.mp4");// 设置网络视频地址
            } else {
                //生产环境
                if (file.getVideoFirstImgKey() != null) {
                    path = file.getVideoFirstImgKey().replace("https", "http");//视频第一帧
                }
                duration = 1;//传大于0的时长  用于判断选对应格式的item布局
                mediaFile.setUrl(file.getVideoPath().replace("https", "http"));// 设置网络视频地址
            }
            mediaFile.setType(FileUpload.MediaFileTypeEnum.VIDEO_FILE.getKey());// 0表示照片，1表示视频
        }
        //附件ID
        mediaFile.setId(file.getId());
        //附件名称
        mediaFile.setFileName(file.getName());
        //附件网络路径
        mediaFile.setPath(path);
        //附件时长
        mediaFile.setDuration(duration);
        //附件后缀
        mediaFile.setFileType(file.getType());

        return mediaFile;
        //添加到文件数组
        //mediaFileList.add(mediaFile);
        //服务器文件id数组
        //uploadIdList.add(mediaFile.getId());
        //设置适配器数据源
        //adapter.setmMediaFileList(mediaFileList);
    }
    ///////////////////////////////////////// 文件名称设置end //////////////////////////////


    /**
     * 拍照或录制后返回的处理方法
     *
     * @return 附件列表
     */
    @NotNull
    private ArrayList<MediaFile> getMediaFiles(String aFilePath) {
        ArrayList<MediaFile> list = new ArrayList<>();
        MediaFile mediaFile = new MediaFile();
        mediaFile.setPath(aFilePath);
        list.add(mediaFile);
        return list;
    }


    /**
     * 选择本地图库文件后的处理方法
     */
    private ArrayList<MediaFile> getMediaFilesForSelectPhotoVideo(@Nullable Intent data) {
        return SelectionManager.getInstance().getmSelectedMediaFileList();
    }

    protected ArrayList<MediaFile> getMediaFileListWhenOnActivityResult(int requestCode, @Nullable Intent data, CustomPickerAdapterShowAndEdit adapter) {
        if (requestCode == System.identityHashCode(adapter) + FileUpload.MediaFileAchieveWayEnum.LOCAL_GALLERY.getKey()) {
            return getMediaFilesForSelectPhotoVideo(data);
        }
        return getMediaFiles(_captureFilePath);
    }

    protected boolean isAdapterImagePickerResult(int requestCode, CustomPickerAdapterShowAndEdit adapter) {
        FileUpload.MediaFileAchieveWayEnum[] values = FileUpload.MediaFileAchieveWayEnum.values();
        for (FileUpload.MediaFileAchieveWayEnum wayEnum : values) {
            if (System.identityHashCode(adapter) + wayEnum.getKey() == requestCode) {
                return true;
            }
        }
        return false;
    }

    /**
     * 显示图片选择跳转的对话框选项。
     */
    private SelectDialog showDialog(SelectDialog.SelectDialogListener listener, List<String> names) {
        SelectionManager.getInstance().clearSelectedMediaFileList();//先清空选择记录
        SelectionManager.getInstance().removeAll();//清空选中记录
        SelectDialog dialog = new SelectDialog(this, R.style.transparentFrameWindowStyle, listener, names);
        if (!this.isFinishing()) {
            dialog.show();
        }
        return dialog;
    }

    protected void saveFileAndRefreshAdapter(ArrayList<MediaFile> list, List<String> addIdList, CustomPickerAdapterShowAndEdit refreshAdapter, FileUpload.RoadInvestigationFileBizTypeEnum fileBizTypeEnum) {
        boolean isSave = true;
        for (int i = 0; i < list.size(); i++) {//遍历设置list中的每一个mediaFile，然后再把list保存到适配器
            MediaFile mediaFile = list.get(i);
            String path = mediaFile.getPath();
            long size = new File(path).length();
            if (size > 150 * 1024 * 1024) {//视频文件不能超过150M
                BamToast.showText(_mContext, getResources().getString(R.string.upload_video_tip));
                isSave = false;
                break;
            } else {
                boolean isImageFile = BitmapFileSetting.isImageFile(path);
                if (isImageFile && size > 30 * 1024 * 1024) {//如果不为空,代表是图片文件,图片文件不能超过10M
                    BamToast.showText(_mContext, getResources().getString(R.string.upload_image_tip));
                    isSave = false;
                    break;
                }
            }
            try {
                double distance;//记录两点的距离
                double lon, lat;//经纬度
                ExifInterface ext = new ExifInterface(path);
                if (ext.hasThumbnail()) {//如果文件有携带经纬度信息,则从文件获取
                    String longitude = ext.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
                    String longitude_ref = ext.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
                    String latitude = ext.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
                    String latitude_ref = ext.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
                    if (longitude != null && latitude != null) {
                        //把经纬度字符串转换为double格式
                        lon = LocationUtils.convertRationalLatLonToDouble(longitude, longitude_ref);
                        lat = LocationUtils.convertRationalLatLonToDouble(latitude, latitude_ref);
                    } else {
                        Location location = GPSUtils.getInstance(_mContext).getLocation();
                        lon = location.getLongitude();
                        lat = location.getLatitude();
                    }
                } else {//如果文件没有经纬度信息,则获取当前用户所在地的经纬度
                    Location location = GPSUtils.getInstance(_mContext).getLocation();
                    lon = location.getLongitude();
                    lat = location.getLatitude();
                }

                mediaFile.setLongitude(lon);
                mediaFile.setLatitude(lat);

                /*mediaFile.setCommentType(commentType.getCommentType()); 替换下面*/
                mediaFile.setCommentType(fileBizTypeEnum.getValue());

                mediaFile.setBizType(fileBizTypeEnum.getKey()); // 必须赋值，调用pmms/file的时候需要用到

                String suffix = PhotoVideoUtil.getSuffix(path);//获取文件的后缀
                mediaFile.setFileType(suffix);

                /*String fileName = fileName_getGenerateFileName(commentType.getComment()) + suffix; 替换下面*/
                /*String fileName = new File(path).getName();
                fileName = DigestUtils.md5DigestAsHex(fileName.getBytes())+suffix;*/
                String fileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;

                mediaFile.setFileName(fileName);

                String lowerCaseSuffix = suffix.toLowerCase();
                if (".mp4".equals(lowerCaseSuffix) || ".mkv".equals(lowerCaseSuffix) || ".wmv".equals(lowerCaseSuffix) || ".avi".equals(lowerCaseSuffix)) {
                    mediaFile.setType(FileUpload.MediaFileTypeEnum.VIDEO_FILE.getKey());
                    mediaFile.setDuration(PhotoVideoUtil.getDuration(path));
                } else {
                    mediaFile.setType(FileUpload.MediaFileTypeEnum.PHOTO_FILE.getKey());
                    mediaFile.setDuration(0);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (isSave) {
            //开始上传文件到服务器。
            _loadingDialog.show();
            doSaveFileToServer(list, (savedFileIdList) -> {
                _loadingDialog.close();
                addIdList.addAll(savedFileIdList);
                refreshAdapter.AddAll(list);//这里添加的时候，会添加该类的mediaList
                refreshAdapter.notifyDataSetChanged();
            });
        }
    }

    // 上传文件到服务器
    private void doSaveFileToServer(ArrayList<MediaFile> addFileList, IFinishUploadCallback iFinishUploadCallback) {
//        _loadingDialog.show();
        OssServiceUtil.initOssService(BaseMediaPickerActivity.this, (String name, OssService service) -> {
            runOnUiThread(() -> {
                _ossService = service;
                _uploadFileHandler = new BaseMediaPickerActivity.UploadFileHandler(BaseMediaPickerActivity.this, this, _loadingDialog, addFileList, _ossService, iFinishUploadCallback);
                _uploadFileHandler.sendEmptyMessage(Constants.UPLOAD);
            });
        }, _loadingDialog);
    }

    private static class UploadFileHandler extends Handler {
        private WeakReference<Activity> mActivityReference;
        private WeakReference<LoadingDialog> mLoadingDialogReference;
        private Queue<MediaFile> uploadFileListQueue = new LinkedList<>();
        private OssService ossService;
        private Context context;
        private ArrayList<String> fileIdList = new ArrayList<>();//附件上传完毕，会返回附件id，业务接口需要使用
        private IFinishUploadCallback iFinishUploadCallback;

        UploadFileHandler(Context context, Activity activity, LoadingDialog loadingDialog, ArrayList<MediaFile> needUploadFileList, OssService ossService, IFinishUploadCallback iFinishUploadCallback) {
            this.context = context;
            this.mActivityReference = new WeakReference<>(activity);
            this.mLoadingDialogReference = new WeakReference<>(loadingDialog);
            this.uploadFileListQueue.addAll(needUploadFileList);
            this.ossService = ossService;
            this.iFinishUploadCallback = iFinishUploadCallback;
        }

        @Override
        public void handleMessage(@NotNull Message msg) {
            super.handleMessage(msg);
            if (this.uploadFileListQueue.size() > 0) {
                MediaFile mediaFile = this.uploadFileListQueue.peek();//取一个出来
                assert mediaFile != null;
                task(mediaFile, msg.what);
            } else {
                if (iFinishUploadCallback != null) {
                    iFinishUploadCallback.finishUploadCallback(fileIdList);
                }
            }
        }

        private void task(MediaFile mediaFile, int flag) {
            LogUtil.i("开始上传附件：", mediaFile.getFileName());
            new Thread(() -> {
                if (Constants.UPLOAD == flag) {
                    ossService.upload(mediaFile, new OssService.UploadCallBack() {
                        @Override
                        public void onSuccess(String result) {
                            //上传成功
                            JSONObject data = JSONObject.parseObject(result).getJSONObject("data");
                            String id = data.getString("id");
                            if (id != null) {
                                LogUtil.i("上传成功一个附件id：", id);
                                fileIdList.add(id);
                            }
                            uploadFileListQueue.poll();
                            sendEmptyMessage(Constants.UPLOAD);
                        }

                        @Override
                        public void onFailure() {
                            if (mLoadingDialogReference != null && mLoadingDialogReference.get() != null) {
                                LoadingDialog loadingDialog = mLoadingDialogReference.get();
                                loadingDialog.close();
                            }
                            if (mActivityReference != null && mActivityReference.get() != null) {
                                Activity activity = mActivityReference.get();
                                BamToast.showText(context, activity.getResources().getString(R.string.netword_error), false);
                            }
                        }
                    });
                }
            }).start();
        }
    }
}
